package de.karlNet.gifSocket;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;

import de.karlNet.gifSocket.controllers.interfaces.ISession;

public class Session implements ISession {
	private static ArrayList<Integer> sessionNumberStorage = new ArrayList<Integer>();
	private BufferedImage lastImage;
	static {
		for (int i = 1000; i < 5001; i++) {
			sessionNumberStorage.add(i);
		}
		Collections.shuffle(sessionNumberStorage);
	}

	private final int sessionNumber;

	private final AnimatedGifEncoder animatedGifEncoder;

	private final MultiplexOutputStream clients;
	private final ScreenshotBuffer screenshotBuffer;
	private final Rectangle captureSize;
	private OutputStream mouseOutputStream;

	public Session(Rectangle captureSize) {
		this.sessionNumber = sessionNumberStorage.get(0);

		this.captureSize = captureSize;
		sessionNumberStorage.remove(0);
		this.animatedGifEncoder = new AnimatedGifEncoder();
		this.clients = new MultiplexOutputStream();
		this.screenshotBuffer = new ScreenshotBuffer(animatedGifEncoder);

		this.lastImage = new BufferedImage(captureSize.width,
				captureSize.height, BufferedImage.TYPE_INT_RGB);

		this.animatedGifEncoder.setRepeat(0);
		this.animatedGifEncoder.start(this.clients);
		this.animatedGifEncoder.addFrame(new BufferedImage(captureSize.width,
				captureSize.height, BufferedImage.TYPE_INT_RGB));
	}

	public void addClient(OutputStream client) {
		AnimatedGifEncoder localGifEncoder = new AnimatedGifEncoder();
		localGifEncoder.setRepeat(0);
		localGifEncoder.start(client);
		localGifEncoder.addFrame(this.lastImage);
		localGifEncoder.addFrame(this.lastImage);

		this.clients.addOutput(client);
	}

	public void addScreenshot(BufferedImage bufferedImage) {
		this.lastImage = bufferedImage;
		this.screenshotBuffer.addScreenshot(bufferedImage);
		this.screenshotBuffer.addScreenshot(bufferedImage);

	}

	public Rectangle getCaptureSize() {
		return captureSize;
	}

	private OutputStream getMouseOutputStream() {
		if (this.mouseOutputStream == null) {
			return new OutputStream() {

				@Override
				public void write(int b) throws IOException {
					// TODO Auto-generated method stub

				}
			};
		}
		return mouseOutputStream;
	}

	public void rightClick(int x, int y) throws IOException {
		byte click = 2;
		System.out.println("right_");
		this.getMouseOutputStream().write(click);

		this.getMouseOutputStream().write(("" + x).getBytes());
		this.getMouseOutputStream().write(("" + y).getBytes());
		this.getMouseOutputStream().write((byte) (0));
		this.getMouseOutputStream().flush();
	}

	public void leftClick(int x, int y) throws IOException {
		byte click = 1;
		System.out.println("click");
		this.getMouseOutputStream().write(click);

		this.getMouseOutputStream().write(("" + x).getBytes());
		this.getMouseOutputStream().write(("" + y).getBytes());
		this.getMouseOutputStream().write((byte) (0));
		this.getMouseOutputStream().flush();
	}

	public int getSessionNumber() {
		return sessionNumber;
	}

	public void setMouseOutputStream(OutputStream mouseOutputStream) {
		System.out.println("registered mouse listener");
		this.mouseOutputStream = mouseOutputStream;
	}
}
